package com.dd.cloud.user.service.pres.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.common.constants.PresConstants;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.utils.BigDecimalUtils;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.user.entity.phar.AuxiliaryMaterialSetting;
import com.dd.cloud.user.entity.phar.AuxiliaryMaterialSettingRecord;
import com.dd.cloud.user.mapper.pres.AuxiliaryMaterialSettingMapper;
import com.dd.cloud.user.req.phar.*;
import com.dd.cloud.user.service.phar.IAuxiliaryMaterialSettingRecordService;
import com.dd.cloud.user.service.phar.IPharSetFeeRecordService;
import com.dd.cloud.user.service.pres.IAuxiliaryMaterialSettingService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 辅料设置 服务实现类
 * </p>
 *
 * @author czg
 * @since 2023-06-06
 */
@Service
public class AuxiliaryMaterialSettingServiceImpl extends ServiceImpl<AuxiliaryMaterialSettingMapper, AuxiliaryMaterialSetting> implements IAuxiliaryMaterialSettingService {

    @Autowired
    private IPharSetFeeRecordService pharSetFeeRecordService;
    @Autowired
    private IAuxiliaryMaterialSettingRecordService auxiliaryMaterialSettingRecordService;

    @Override
    public Page<AuxiliaryMaterialSetting> getAuxiliaryMaterialSettingPage(AuxiliarySettingReq req) {
        if (req.getPharId() == null) {
            LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
            req.setPharId(loginInfo.getPharId());
        }
        if (StringUtils.isBlank(req.getStatus())) {
            req.setStatusList(PresConstants.AuxiliaryMaterialStatus.status);
        } else {
            List<Integer> status = Arrays.stream(req.getStatus().split(","))
                    .map(s -> Integer.parseInt(s.trim())).collect(Collectors.toList());
            req.setStatusList(status);
        }
        LambdaQueryWrapper<AuxiliaryMaterialSetting> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(AuxiliaryMaterialSetting::getStatus, req.getStatusList())
                .eq(AuxiliaryMaterialSetting::getPharId, req.getPharId())
                .orderByAsc(AuxiliaryMaterialSetting::getSort);
        Page<AuxiliaryMaterialSetting> page = req.pagePojo();
        Page<AuxiliaryMaterialSetting> res = this.getBaseMapper().selectPage(page, wrapper);
        return res;
    }

    @Override
    public AuxiliaryMaterialSetting getAuxiliaryDetail(Integer id) {
        return this.getById(id);
    }

    @Override
    public void updateAuxiliaryStatus(Integer id, Integer status) {
        LambdaUpdateWrapper<AuxiliaryMaterialSetting> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(AuxiliaryMaterialSetting::getStatus, status)
                .eq(AuxiliaryMaterialSetting::getId, id);
        this.update(updateWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addAuxiliarySetting(AddAuxiliarySettingReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        LambdaQueryWrapper<AuxiliaryMaterialSetting> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AuxiliaryMaterialSetting::getName, req.getName())
                .ne(AuxiliaryMaterialSetting::getStatus, PresConstants.ModelDrugsStatus.DEL)
                .eq(AuxiliaryMaterialSetting::getPharId, loginInfo.getPharId());
        int count = this.getBaseMapper().selectCount(wrapper);
        if (count > 0) {
            throw new ZekeException("辅料设置名称已存在");
        }
        List<AuxiliaryMaterialSetting> newlist = null;
        if (req.getSort() == null) {
            LambdaQueryWrapper<AuxiliaryMaterialSetting> qw = new LambdaQueryWrapper<>();
            qw.ne(AuxiliaryMaterialSetting::getStatus, PresConstants.ModelDrugsStatus.DEL)
                    .orderByDesc(AuxiliaryMaterialSetting::getSort)
                    .last("limit 1");
            AuxiliaryMaterialSetting auxiliaryMaterialSetting = this.getBaseMapper().selectOne(qw);
            if (auxiliaryMaterialSetting == null) {
                req.setSort(1);
            } else {
                req.setSort(auxiliaryMaterialSetting.getSort() + 1);
            }
        } else {
            LambdaQueryWrapper<AuxiliaryMaterialSetting> qw = new LambdaQueryWrapper<>();
            qw.ne(AuxiliaryMaterialSetting::getStatus, PresConstants.ModelDrugsStatus.DEL)
                    .orderByAsc(AuxiliaryMaterialSetting::getSort);
            List<AuxiliaryMaterialSetting> list = this.getBaseMapper().selectList(qw);
            if (CollectionUtils.isNotEmpty(list)) {
                List<Integer> sortList = list.stream().map(AuxiliaryMaterialSetting::getSort).collect(Collectors.toList());
                if (sortList.contains(req.getSort())) {
                    newlist = list.stream().filter(item -> item.getSort() >= req.getSort()).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(newlist)) {
                        newlist.forEach(item -> item.setSort(item.getSort() + 1));
                    }
                }
            }
        }
        AuxiliaryMaterialSetting auxiliaryMaterialSetting = new AuxiliaryMaterialSetting();
        BeanUtil.copyProperties(req, auxiliaryMaterialSetting);
        auxiliaryMaterialSetting.setPharId(loginInfo.getPharId())
                .setUpdateDate(LocalDateTime.now())
                .setCreateDate(LocalDateTime.now())
                .setStatus(PresConstants.PresDrugsStatus.NOMER);
        Boolean flag = this.save(auxiliaryMaterialSetting);
        if (flag && CollectionUtils.isNotEmpty(newlist)) {
            this.updateBatchById(newlist);
        }
    }

    @Override
    public void updateAuxiliarySetting(UpdateAuxiliarySettingReq newData) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        Integer id = newData.getId();
        AuxiliaryMaterialSetting auxiliaryMaterialSetting = this.getById(id);
        if (!newData.getName().equals(auxiliaryMaterialSetting.getName())) {
            LambdaQueryWrapper<AuxiliaryMaterialSetting> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(AuxiliaryMaterialSetting::getName, newData.getName())
                    .ne(AuxiliaryMaterialSetting::getStatus, PresConstants.ModelDrugsStatus.DEL)
                    .eq(AuxiliaryMaterialSetting::getPharId, loginInfo.getPharId());
            int count = this.getBaseMapper().selectCount(wrapper);
            if (count > 0) {
                throw new ZekeException("辅料设置名称已存在");
            }
        }
        List<AuxiliaryMaterialSetting> newlist = null;
        if (newData.getSort() == null) {
            LambdaQueryWrapper<AuxiliaryMaterialSetting> qw = new LambdaQueryWrapper<>();
            qw.ne(AuxiliaryMaterialSetting::getStatus, PresConstants.ModelDrugsStatus.DEL)
                    .orderByDesc(AuxiliaryMaterialSetting::getSort)
                    .last("limit 1");
            AuxiliaryMaterialSetting res = this.getBaseMapper().selectOne(qw);
            if (res == null) {
                newData.setSort(1);
            } else {
                newData.setSort(auxiliaryMaterialSetting.getSort() + 1);
            }
        } else {
            if (!auxiliaryMaterialSetting.getSort().equals(newData.getSort())) {
                LambdaQueryWrapper<AuxiliaryMaterialSetting> qw = new LambdaQueryWrapper<>();
                qw.ne(AuxiliaryMaterialSetting::getStatus, PresConstants.ModelDrugsStatus.DEL)
                        .ne(AuxiliaryMaterialSetting::getId, id)
                        .orderByAsc(AuxiliaryMaterialSetting::getSort);
                List<AuxiliaryMaterialSetting> list = this.getBaseMapper().selectList(qw);
                if (CollectionUtils.isNotEmpty(list)) {
                    List<Integer> sortList = list.stream().map(AuxiliaryMaterialSetting::getSort).collect(Collectors.toList());
                    if (sortList.contains(newData.getSort())) {
                        newlist = list.stream().filter(item -> item.getSort() >= newData.getSort()).collect(Collectors.toList());
                        if (CollectionUtils.isNotEmpty(newlist)) {
                            newlist.forEach(item -> item.setSort(item.getSort() + 1));
                        }
                    }
                }
            }
        }
        UpdateAuxiliarySettingReq oldData = new UpdateAuxiliarySettingReq();
        BeanUtil.copyProperties(auxiliaryMaterialSetting, oldData);
        //转换数据
        UpdateAuxiliarySettingRecord oldRecord = convertData(oldData);
        UpdateAuxiliarySettingRecord newRecord = convertData(newData);
        String result = com.dd.cloud.common.utils.BeanUtils.getChangedFields(oldRecord, newRecord);
        //更新
        BeanUtil.copyProperties(newData, auxiliaryMaterialSetting);
        auxiliaryMaterialSetting.setUpdateDate(LocalDateTime.now());
        Boolean flag = this.updateById(auxiliaryMaterialSetting);
        if (flag && StringUtils.isNotBlank(result)) {
            //去除最后的一个逗号
            result = result.substring(0, result.length() - 1);
            AuxiliaryMaterialSettingRecord pharSetFeeRecord = new AuxiliaryMaterialSettingRecord();
            pharSetFeeRecord.setUpdateDate(LocalDateTime.now())
                    .setAuxiliaryId(auxiliaryMaterialSetting.getId())
                    .setUpdateName(loginInfo.getName())
                    .setUpdateContent(result);
            auxiliaryMaterialSettingRecordService.save(pharSetFeeRecord);
        }
        if (flag && CollectionUtils.isNotEmpty(newlist)) {
            this.updateBatchById(newlist);
        }
    }

    @Override
    public IPage<AuxiliaryMaterialSettingRecord> getRecord(AuxiliarySettingRecordReq req) {
        LambdaQueryWrapper<AuxiliaryMaterialSettingRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AuxiliaryMaterialSettingRecord::getAuxiliaryId, req.getId())
                .orderByDesc(AuxiliaryMaterialSettingRecord::getUpdateDate);
        IPage<AuxiliaryMaterialSettingRecord> page = req.pagePojo();
        IPage<AuxiliaryMaterialSettingRecord> recordIPage = auxiliaryMaterialSettingRecordService.getBaseMapper().selectPage(page, wrapper);
        return recordIPage;
    }

    @Override
    public AuxiliaryMaterialSetting queryFeePrice(Integer pharId) {
        LambdaQueryWrapper<AuxiliaryMaterialSetting> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AuxiliaryMaterialSetting::getName, "蜂蜜")
                .eq(AuxiliaryMaterialSetting::getStatus, 1)
                .eq(AuxiliaryMaterialSetting::getPharId, pharId);
        AuxiliaryMaterialSetting auxiliaryMaterialSetting = this.getOne(wrapper);
        return auxiliaryMaterialSetting;
    }

    private UpdateAuxiliarySettingRecord convertData(UpdateAuxiliarySettingReq data) {
        UpdateAuxiliarySettingRecord updateAuxiliarySettingRecord = new UpdateAuxiliarySettingRecord();
        updateAuxiliarySettingRecord.setName(data.getName())
                .setUnit(data.getUnit())
                .setPrice(BigDecimalUtils.divide(new BigDecimal(data.getPrice()), new BigDecimal(100), 2) + "元")
                .setOriginalPrice(BigDecimalUtils.divide(new BigDecimal(data.getOriginalPrice() == null ? 0 : data.getOriginalPrice()),
                        new BigDecimal(100), 2) + "元")
                .setSort(data.getSort() == null ? "未设置" : data.getSort() + "")
                .setRemark(data.getRemark() == null ? "未设置" : data.getRemark());
        return updateAuxiliarySettingRecord;
    }
}
